local fn = vim.fn

local install_path = fn.stdpath("data") .. "/site/pack/packer/start/packer.nvim"
if fn.empty(fn.glob(install_path)) > 0 then
	packer_bootstrap =
	fn.system({ "git", "clone", "--depth", "1", "https://github.com/wbthomason/packer.nvim", install_path })
end

return require("packer").startup({

	function(use)
		-- Packer itself
		use("wbthomason/packer.nvim")

		-- Lua library
		use("nvim-lua/plenary.nvim")

		------------------------------------------------------------------------
		------------------------ Visual Plugins --------------------------------
		------------------------------------------------------------------------

		-- A colour schema
		use({
			"rose-pine/neovim",
			-- disable = true,
			as = "rose-pine",
			tag = "v1.*",
			config = [[require('plugins.config.rose_pine')]],
		})

		use({
			"catppuccin/nvim",
			-- disable = true,
			as = "catppuccin",
			config = [[require('plugins.config.catppuccin')]],
		})

		use({
			"lukas-reineke/indent-blankline.nvim",
			-- disable = true,
			opt = true,
			event = "BufReadPost",
			config = [[require('plugins.config.indent-blankline')]],
		})

		-- A statsu line
		use({
			"nvim-lualine/lualine.nvim",
			-- disable = true,
			-- opt = false,
			-- fix mismatch palette between variants
			-- event = 'ColorScheme',
			after = "nvim-gps",
			config = [[require('plugins.config.lualine')]],
		})

		use({
			"j-hui/fidget.nvim",
			opt = true,
			event = "BufReadPost",
			config = function()
				require("fidget").setup({})
			end,
		})

		use({
			"akinsho/bufferline.nvim",
			-- disable = true,
			tag = "*",
			requires = "kyazdani42/nvim-web-devicons",
			event = "BufReadPost",
			config = [[require('plugins.config.bufferline')]],
		})

		use({
			"folke/twilight.nvim",
			-- disable = true,
			cmd = {
				"Twilight",
				"TwilightEanble",
				"TwilightDisable",
			},
			config = [[require('plugins.config.twilight')]],
		})

		use({
			"folke/trouble.nvim",
			-- disable = true,
			requires = "kyazdani42/nvim-web-devicons",
			cmd = {
				"Trouble",
				"TroubleToggle",
				"TroubleRefresh",
			},
			-- after = 'nvim-web-devicons',
			config = [[require('plugins.config.trouble')]],
		})

		use({
			"goolord/alpha-nvim",
			opt = true,
			event = "BufWinEnter",
			config = [[require('plugins.config.alpha-nvim')]],
		})

		------------------------------------------------------------------------
		------------------------  File managements  ----------------------------
		------------------------------------------------------------------------
		use({
			"nvim-telescope/telescope.nvim",
			opt = true,
			module = "telescope",
			cmd = "Telescope",
			requires = {
				{ "nvim-lua/plenary.nvim" },
				{ "nvim-lua/popup.nvim", opt = true },
			},
			config = [[require('plugins.config.telescope')]],
		})

		-- A C port of fzf
		use({
			"nvim-telescope/telescope-fzf-native.nvim",
			opt = true,
			-- run = "make",
			run = "cmake -S. -Bbuild -DCMAKE_BUILD_TYPE=Release && cmake --build build --config Release && cmake --install build --prefix build",
			after = "telescope.nvim",
		})
		-- Search and switch between projects
		use({ "nvim-telescope/telescope-project.nvim", opt = true, after = "telescope-fzf-native.nvim" })
		-- A recently used file sorter
		use({
			"nvim-telescope/telescope-frecency.nvim",
			opt = true,
			after = "telescope-project.nvim",
			requires = { { "kkharji/sqlite.lua", opt = true } },
		})

		use({
			"nvim-telescope/telescope-file-browser.nvim",
			opt = true,
		})

		------------------------------------------------------------------------
		------------------------ Editor accessaries ----------------------------
		------------------------------------------------------------------------

		-- Replace cursorword
		use({
			"RRethy/vim-illuminate",
			event = "BufReadPost",
			config = function()
				vim.g.Illuminate_highlightUnderCursor = 0
				vim.g.Illuminate_ftblacklist = {
					"help",
					"dashboard",
					"alpha",
					"packer",
					"norg",
					"DoomInfo",
					"NvimTree",
					"Outline",
					"toggleterm",
				}
			end,
		})

		use({
			"edluffy/specs.nvim",
			-- disable = true,
			event = "CursorMoved",
			config = [[require('plugins.config.specs')]],
		})

		-- Icon supports for other plugins
		use({
			"kyazdani42/nvim-web-devicons",
			-- disable = true,
		})

		-- Hint for mappings
		use({
			"folke/which-key.nvim",
			-- disable = true,
			config = [[require('plugins.config.which-key')]],
		})

		-- A lightwight file tree
		use({
			"kyazdani42/nvim-tree.lua",
			-- disable = true,
			cmd = { "NvimTreeToggle" },
			config = [[require('plugins.config.nvim-tree')]],
		})

		-- An undo tree
		use({
			"mbbill/undotree",
			opt = true,
			cmd = "UndotreeToggle",
		})

		-- commnent, use mapping gc
		use({
			"terrortylor/nvim-comment",
			-- disable = true,
			config = function()
				require("nvim_comment").setup({
					-- Linters prefer comment and line to have a space in between markers
					marker_padding = true,
					-- should comment out empty or whitespace only lines
					comment_empty = true,
					-- Should key mappings be created
					create_mappings = true,
					-- Normal mode mapping left hand side
					line_mapping = "gcc",
					-- Visual/Operator mapping left hand side
					operator_mapping = "gc",
					-- Hook function to call before commenting takes place
					hook = function()
						require("ts_context_commentstring.internal").update_commentstring()
					end,
				})
			end,
		})

		use({
			"famiu/bufdelete.nvim",
			-- disable = true,
			opt = true,
			cmd = { "Bdelete", "Bwipeout", "Bdelete!", "Bwipeout!" },
		})

		-- Enhance the build in filetype
		use({
			"nathom/filetype.nvim",
			-- disable = true,
		})

		use({
			"phaazon/hop.nvim",
			-- disable = true,
			opt = true,
			event = "BufReadPost",
			config = function()
				require("hop").setup({ keys = "fjrucntyghvbeidkxmwoslqazp" })
			end,
		})

		------------------------------------------------------------------------
		------------------------- Coding accessaries ---------------------------
		------------------------------------------------------------------------

		------------------------------------------------------------------------
		------------------------- Tree sitter related --------------------------
		------------------------------------------------------------------------

		use({
			"nvim-treesitter/nvim-treesitter",
			opt = true,
			-- disable = true,
			run = ":TSUpdate",
			event = "BufReadPost",
			config = [[require('plugins.config.nvim-treesitter')]],
			requires = {
				"nvim-treesitter/nvim-treesitter-textobjects",
				"nvim-treesitter/nvim-treesitter-refactor",
				"JoosepAlviste/nvim-ts-context-commentstring",
				{
					"p00f/nvim-ts-rainbow",
					-- disable = true,
					event = "BufReadPost",
				},
			},
		})

		-- Show position in status line
		use({
			"SmiteshP/nvim-gps",
			-- disable = true,
			after = "nvim-treesitter",
			config = [[require('plugins.config.nvim-gps')]],
		})

		------------------------------------------------------------------------
		---------------------------- Lsp related -------------------------------
		-----------------------------sumneko_lua-------------------------------------------

		-- Lsp configuration
		use({
			"neovim/nvim-lspconfig",
			-- disable = true,
			-- after = 'aerial.nvim',
			opt = true,
			event = "BufReadPre",
			config = [[require('plugins.config.nvim-lspconfig')]],
		})

		-- The 3rd party tools manager, such as lsp, dap
		use({
			"williamboman/mason.nvim",
			-- disable = true,
			opt = false,
			requires = {
				{
					-- As a bridge between lspconfig and mason
					"williamboman/mason-lspconfig.nvim",
				},
				{
					"WhoIsSethDaniel/mason-tool-installer.nvim",
					config = [[require('plugins.config.mason-tool-installer')]],
				},
			},
			-- config = [[require('plugins.config.nvim-lsp-installer')]],
		})

		use({
			"ray-x/lsp_signature.nvim",
			-- disable = true,
			after = "nvim-lspconfig",
			opt = true,
			config = [[require('plugins.config.lsp_signature')]],
		})

		-- Some enhancements of lsp basic functions
		-- with icons and popup window
		use({
			"tami5/lspsaga.nvim",
			-- disable = true,
			branch = "nvim7.0",
		})

		use({
			"stevearc/aerial.nvim",
			-- disable = true,
			opt = true,
			config = [[require('plugins.config.aerial')]],
			after = "nvim-lspconfig",
		})

		------------------------------------------------------------------------
		----------------------------- Cmp related ------------------------------
		------------------------------------------------------------------------

		-- Autocompletion plugin
		use({
			"hrsh7th/nvim-cmp",
			-- disable = true,
			event = "InsertEnter *",
			config = [[require('plugins.config.nvim-cmp')]],
			requires = {
				-- Snippets plugin
				{
					"L3MON4D3/LuaSnip",
					-- Vscode style snippets
					requires = "rafamadriz/friendly-snippets",
					config = function()
						local global = require('options.global')
						vim.o.runtimepath = vim.o.runtimepath
							.. ","
							.. global.home
							.. (global.is_windows and "\\nvim\\my-snippets\\," or "/.config/nvim/my-snippets/,")
						require("luasnip").config.set_config({
							history = true,
							updateevents = "TextChanged,TextChangedI",
						})
						require("luasnip.loaders.from_lua").lazy_load()
						require("luasnip.loaders.from_vscode").lazy_load()
						require("luasnip.loaders.from_snipmate").lazy_load()
					end,
				},
				{ "onsails/lspkind-nvim" },
				-- Source of neovim's build-in lsp
				{ "hrsh7th/cmp-nvim-lsp" },
				-- Source of neovim Lua API
				-- Snippets source
				{ "hrsh7th/cmp-nvim-lsp-signature-help", after = "nvim-cmp" },
				{ "hrsh7th/cmp-nvim-lua", after = "nvim-cmp" },
				{ "hrsh7th/cmp-path", after = "nvim-cmp" },
				{ "hrsh7th/cmp-buffer", after = "nvim-cmp" },
				{ "hrsh7th/cmp-cmdline", after = "nvim-cmp" },
				-- { 'hrsh7th/cmp-nvim-lsp-document-symbol', after = 'nvim-cmp' },
				{ "saadparwaiz1/cmp_luasnip", after = "nvim-cmp" },
				{
					"uga-rosa/cmp-dictionary",
					after = "nvim-cmp",
					config = [[require('plugins.config.cmp-dictionary')]],
				},
				-- { 'f3fora/cmp-spell'},
				-- { 'petertriho/cmp-git' },
			},
		})

		------------------------------------------------------------------------
		---------------------------- Debug adapter -----------------------------
		------------------------------------------------------------------------

		use({
			"mfussenegger/nvim-dap",
			opt = true,
			cmd = {
				"DapSetLogLevel",
				"DapShowLog",
				"DapContinue",
				"DapToggleBreakpoint",
				"DapToggleRepl",
				"DapStepOver",
				"DapStepInto",
				"DapStepOut",
				"DapTerminate",
			},
			module = "dap",
			config = [[require('plugins.config.nvim-dap')]],
		})

		use({
			"rcarriga/nvim-dap-ui",
			opt = true,
			config = [[require('plugins.config.nvim-dap-ui')]],
		})

		-- Auto pair quates
		use({
			"windwp/nvim-autopairs",
			-- disable = true,
			after = "nvim-cmp",
			config = [[require('plugins.config.nvim-autopairs')]],
		})

		-- Automatically set up your configuration after cloning packer.nvim
		-- Put this at the end after all plugins
		if packer_bootstrap then
			require("packer").sync()
		end
	end,

	-- Packer configurations
	config = {
		display = {
			open_fn = require("packer.util").float,
		},
		profile = {
			enable = true,
			threshold = 1,
		},
	},
})
